#pragma once
#include"Socket.hpp"
#include<iostream>
#include<memory.h>
#include<sys/wait.h>
#include<functional>
using namespace SocketModule;
using ioserve_t = std::function<void(std::shared_ptr<Socket>& socket,InetAddr& addr)>;
class Tcpserve
{
public:
    Tcpserve(uint16_t port)
    :_port(port)
    ,_listensocketptr(std::make_unique<TcpSocket>())
    ,_isrunning(false)
   
    {
        _listensocketptr->BulidListenSocketMethod(_port);
    };
    void Start(ioserve_t calbackfunc)
    {
        _isrunning=true;
        while(_isrunning)
        {
            InetAddr client;
            auto sockfd=_listensocketptr->Accept(&client);
            LOG(LogLevel::INFO)<<"accept success"<<client.StringAddr();
            if(sockfd==nullptr)
            {
                continue;
            }
            LOG(LogLevel::DEBUG)<<"accept success....";
            pid_t id=fork();
            if(id<0)
            {
                LOG(LogLevel::FATAL)<<"fork error";
                exit(1);
            }
            else if(id==0)
            {
                _listensocketptr->Close();
                if(fork()>0)
                {
                    exit(OK);
                }
                calbackfunc(sockfd,client);
                exit(OK);
            }   
            else
            {
                sockfd->Close();
                int m=waitpid(id,nullptr,0);
                (void)m;
            }
            
        }
        _isrunning=false;
    }

    ~Tcpserve(){};
    

private:
     uint16_t _port;
     std::unique_ptr<Socket> _listensocketptr;
     bool _isrunning;
     ioserve_t _serve;
};